package com.feng.config;

import com.feng.dto.LoginUser;
import com.feng.dto.Result;
import com.feng.pojo.User;
import com.feng.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
@Slf4j
public class LoginAOP {

    @Autowired
    RedisService redisService;

    @Pointcut("execution (* com.feng.controller.*.*(..))  && !@annotation(com.feng.config.PassToken)")
    public void test() {

    }

    @Around("test()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
        LoginUser loginUser = new LoginUser();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Cookie[] cookies = request.getCookies();

        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("uuid")) {
                    String uuid = cookie.getValue();
                    User user = redisService.get(uuid, User.class);
                    if (user != null) {
                        try {
                            Object[] args = proceedingJoinPoint.getArgs();
                            for (Object arg : args) {
                                if (arg instanceof LoginUser) {
                                    BeanUtils.copyProperties(user, arg);
                                    BeanUtils.copyProperties(user, loginUser);
                                }
                            }
                            return proceedingJoinPoint.proceed();
                        } catch (Throwable t) {
                            log.error("aop拦截遇到错误", t);
                            return Result.builder().success(false).massage(t.getMessage()).build();
                        }
                    }
                    return Result.builder().success(false).massage("令牌缺失或过期").build();
                }
            }
            return Result.builder().success(false).massage("令牌缺失或过期").build();
        }
        return Result.builder().success(false).massage("令牌缺失或过期").build();
    }
}
